package com.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.media.ExifInterface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.provider.MediaStore;
import android.telephony.TelephonyManager;
import android.util.Log;

public class Utils {

	// RETURN BITMAP FROM FILE
	public static Bitmap decodeFileExact(File f, int maxWidth, int maxHeight) {
		Bitmap ret = null;
		try {
			// Decode image size
			BitmapFactory.Options o = new BitmapFactory.Options();
			o.inJustDecodeBounds = true;
			BitmapFactory.decodeStream(new FileInputStream(f), null, o);
			BitmapFactory.Options o2 = new BitmapFactory.Options();
			o2.inSampleSize = Math.max(o.outWidth / (maxWidth * 2), o.outHeight
					/ (maxHeight * 2));
			ret = BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
			int width_tmp = o.outWidth;
			int height_tmp = o.outHeight;
			if ((ret.getWidth() > maxWidth) || (ret.getHeight() > maxHeight)) {
				float scale = Math.min((maxWidth * 1.0F) / width_tmp,
						(maxHeight * 1.0F) / height_tmp);
				Matrix matrix = new Matrix();
				matrix.postScale(scale, scale);
				Bitmap resizedBitmap = Bitmap.createBitmap(ret, 0, 0,
						width_tmp, height_tmp, matrix, true);
				ret = resizedBitmap;

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret;
	}

	// RETURN BITMAP FROM FILE
	// public static Bitmap decodeFile(File f, int maxWidth, int maxHeight) {
	// Bitmap ret = null;
	// try {
	// // Decode image size
	// BitmapFactory.Options o = new BitmapFactory.Options();
	// o.inJustDecodeBounds = true;
	// BitmapFactory.decodeStream(new FileInputStream(f), null, o);
	// BitmapFactory.Options o2 = new BitmapFactory.Options();
	// o2.inSampleSize = Math.max(o.outWidth / (maxWidth), o.outHeight
	// / (maxHeight));
	// Log.i("DREG", "SAMPLE_SIZE=" + o.outWidth + "x" + o.outHeight + "x"
	// + o2.inSampleSize);
	// ret = BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
	//
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// return ret;
	// }

	// RETURN IMAGE DATA FROM FILE (IF FILE IS LARGER THEN MAKE THE IMAGE
	// SMALLER THEN RETURN BYTES)
	public static byte[] getImageData(File file, int maxDim) throws Exception {
		Bitmap bitmap = decodeFile(file, maxDim, maxDim);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		if (file.getName().toLowerCase().endsWith(".jpg")
				|| file.getName().toLowerCase().endsWith(".jpeg")) {
			bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);
		} else {
			bitmap.compress(Bitmap.CompressFormat.PNG, 80, baos);
		}
		return baos.toByteArray();
	}

	public static String getRealPathFromURI(Uri contentUri, Activity activity)
			throws Exception {
		String[] proj = { MediaStore.Images.Media.DATA };
		Cursor cursor = activity.managedQuery(contentUri, proj, null, null,
				null);
		int column_index = cursor
				.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		cursor.moveToFirst();
		String ret = cursor.getString(column_index);
		cursor.close();
		return ret;
	}

	public static File convertImageUriToFile(Uri imageUri, Activity activity)
			throws Exception {
		String path = getRealPathFromURI(imageUri, activity);
		if (path != null) {
			return new File(path);
		} else {
			return null;
		}
	}

	public static boolean isOnline(Activity activity) {
		ConnectivityManager cm = (ConnectivityManager) activity
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo i = cm.getActiveNetworkInfo();
		if (i == null)
			return false;
		if (!i.isConnected())
			return false;
		if (!i.isAvailable())
			return false;
		return true;
	}

	public static String getDeviceId(Context context) throws Exception {
		String ret = "no_key";
		TelephonyManager telephonyManager = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
		ret = telephonyManager.getDeviceId();
		if (ret == null) {
			// ret = "no_key";
			throw new Exception("This is not a cell phone");
		}
		return ret;
		// return "353328059721025";
	}

	@SuppressWarnings("static-access")
	public static String getPhoneNumber(Context context) {
		// return ((TelephonyManager) context
		// .getSystemService(context.TELEPHONY_SERVICE)).getLine1Number();
		return null;
	}

	public static final ProgressDialog getProgressDialog(Context context,
			String title, String message) {
		ProgressDialog progressDialog = new ProgressDialog(context);
		progressDialog.setTitle(title);
		progressDialog.setMessage(message);
		progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		progressDialog.setCancelable(true);
		progressDialog.setIndeterminate(true);
		return progressDialog;
	}

	public static void showAlertMessage(Context context, String title,
			String message) {
		final AlertDialog.Builder builder = new AlertDialog.Builder(context);
		builder.setMessage(message)
				.setCancelable(false)
				.setPositiveButton(context.getString(R.string.ok),
						new DialogInterface.OnClickListener() {
							public void onClick(final DialogInterface dialog,
									final int id) {

							}
						});
		final AlertDialog alert = builder.create();
		alert.setTitle(title);
		alert.show();
	}

	public static final String generateKey(int length) {
		String key = "";
		for (int i = 0; i < length; i++) {
			key += Integer.toString((int) (10 * Math.random()));
		}
		return key;
	}

	public static final String getDeviceInfo() {
		String ret = "";
		try {
			ret += "";
			ret += "\n";
			ret += "\n-----------------------------";
			ret += "\nManufacturer:" + android.os.Build.BOARD;
			ret += "\nDevice: " + android.os.Build.DEVICE;
			ret += "\nBrand: " + android.os.Build.BRAND;
			ret += "\nOS: " + android.os.Build.VERSION.RELEASE;
			ret += "\nBuild:" + android.os.Build.DISPLAY;

		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret;
	}

	public static final Pattern EMAIL_ADDRESS_PATTERN = Pattern
			.compile("[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" + "\\@"
					+ "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" + "(" + "\\."
					+ "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" + ")+");

	public static boolean checkEmail(String email) {
		return EMAIL_ADDRESS_PATTERN.matcher(email).matches();
	}

	public static final Pattern URL_PATTERN = Pattern
			.compile("(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]");

	public static boolean checkURL(String url) {
		return URL_PATTERN.matcher(url).matches();
	}

	public static List<String> getLRLS(String text) {
		List<String> ls = new ArrayList<String>();
		if (text != null) {
			Pattern p = Pattern
					.compile("\\b((https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|])");
			Matcher m = p.matcher(text);
			while (m.find()) {
				String url = m.group(1);
				if (!ls.contains(url)) {
					ls.add(url);
				}
			}
		}
		return ls;
	}

	public static String getEncodedString(String str) {
		String ret = null;
		try {
			ret = Base64.encode(str.getBytes(Constants.ENCODING_TYPE));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret;
	}

	public static String getDecodedString(String str) {
		String ret = null;
		try {
			ret = new String(Base64.decode(str), Constants.ENCODING_TYPE);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret;
	}

	public static final String[] getThreeProbabableEncodedKeys(final String key) {
		String[] ret = new String[3];
		int len = key.length();
		int mod = len % 3;
		String encoded = getEncodedString(key);
		if (mod == 0) {
			ret[0] = encoded;
		} else {
			ret[0] = encoded.substring(0, encoded.length() - 3);
		}

		mod = (len + 1) % 3;
		encoded = getEncodedString("_" + key);
		if (mod == 0) {
			ret[1] = encoded.substring(2);
		} else {
			ret[1] = encoded.substring(2, encoded.length() - 3);
		}

		mod = (len + 2) % 3;
		encoded = getEncodedString("__" + key);
		if (mod == 0) {
			ret[2] = encoded.substring(3);
		} else {
			ret[2] = encoded.substring(3, encoded.length() - 3);
		}
		return ret;
	}

	// public static String getHexString(String str){
	// String ret = null;
	// try {
	// ret = Base64.encode(str.getBytes(Constants.ENCODING_TYPE));
	// // ret = Base64.encodeToString(str.getBytes(Constants.ENCODING_TYPE),
	// Base64.DEFAULT);
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// return ret;
	// }
	//
	// public static String toHexString(byte[] bytes) {
	// char[] hexArray =
	// {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
	// char[] hexChars = new char[bytes.length * 2];
	// int v;
	// for ( int j = 0; j < bytes.length; j++ ) {
	// v = bytes[j] & 0xFF;
	// hexChars[j*2] = hexArray[v/16];
	// hexChars[j*2 + 1] = hexArray[v%16];
	// }
	// return new String(hexChars);
	// }
	//
	// public static String toHexString(String str) {
	// return toHexString(str.getBytes());
	// }

	public static File convertImageUriToFile(Uri imageUri, Context context)
			throws Exception {
		String path = getRealPathFromURI(imageUri, context);
		if (path != null) {
			return new File(path);
		} else {
			return null;
		}
	}

	public static String getRealPathFromURI(Uri contentUri, Context context)
			throws Exception {

		String ret = null;
		// can post image
		String[] proj = { MediaStore.Images.Media.DATA };
		Cursor cursor = context.getContentResolver().query(contentUri, proj, // Which
																				// columns
				// to return
				null, // WHERE clause; which rows to return (all rows)
				null, // WHERE clause selection arguments (none)
				null); // Order-by clause (ascending by name)
		int column_index = cursor
				.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		if (cursor.moveToFirst()) {
			ret = cursor.getString(column_index);
		}
		cursor.close();
		return ret;
	}
	
	public static String getPath(Context a, Uri uri) {
		String[] projection = { MediaStore.Images.Media.DATA };
		Cursor cursor = a.getContentResolver().query(uri, projection, null, null, null);
		int column_index = cursor
				.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		cursor.moveToFirst();
		String path = cursor.getString(column_index);
		cursor.close();
		return path;
	}

	public static final String getException(Exception ex) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			PrintWriter pr = new PrintWriter(baos);
			ex.printStackTrace(pr);
			pr.close();
			byte[] ret = baos.toByteArray();
			baos.close();
			return new String(ret);
		} catch (Exception e) {
			return null;
		}

	}

	public static Bitmap decodeFile(File f, int width, int height)
			throws Exception {
		Bitmap ret = null;
		Bitmap temp = decodeSampledBitmapFromFile(f.getAbsolutePath(), width,
				height);// BitmapFactory.decodeStream(new FileInputStream(f));
		ret = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
		Canvas comboImage = new Canvas(ret);

		Rect rDest = new Rect(0, 0, width, height);
		int min = Math.min(temp.getWidth(), temp.getHeight());
		Rect rSrc = new Rect((temp.getWidth() - min) / 2,
				(temp.getHeight() - min) / 2, (temp.getWidth() + min) / 2,
				(temp.getHeight() + min) / 2);
		comboImage.drawBitmap(temp, rSrc, rDest, null);
		// Paint paint = new Paint();
		// paint.setColor(0xFF525252);
		// comboImage.drawLine(0, 0, width - 1, 0, paint);
		// comboImage.drawLine(0, width - 1, width - 1, width - 1, paint);
		// comboImage.drawLine(0, 0, 0, width - 1, paint);
		// comboImage.drawLine(width - 1, 0, width - 1, width - 1, paint);
		comboImage.save();
		return ret;
	}

	public static Bitmap decodeSampledBitmapFromFile(String filename,
			int reqWidth, int reqHeight) throws Exception {

		// First decode with inJustDecodeBounds=true to check dimensions
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(filename, options);

		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, reqWidth,
				reqHeight);

		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;

		Bitmap bmp = BitmapFactory.decodeFile(filename, options);

		ExifInterface exif = new ExifInterface(filename);
		int orientation = exif
				.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
		Matrix matrix = new Matrix();
		switch (orientation) {
		case 3:
			matrix.postRotate(180);
			bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
					bmp.getHeight(), matrix, true);
			break;
		case 6:
			matrix.postRotate(90);
			bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
					bmp.getHeight(), matrix, true);
			break;
		case 8:
			matrix.postRotate(270);
			bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
					bmp.getHeight(), matrix, true);
			break;
		default:
			break;
		}

		return bmp;
	}

	public static int calculateInSampleSize(BitmapFactory.Options options,
			int reqWidth, int reqHeight) throws Exception {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {

			// Calculate ratios of height and width to requested height and
			// width
			final int heightRatio = Math.round((float) height
					/ (float) reqHeight);
			final int widthRatio = Math.round((float) width / (float) reqWidth);

			// Choose the smallest ratio as inSampleSize value, this will
			// guarantee a final image
			// with both dimensions larger than or equal to the requested height
			// and width.
			inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

			// This offers some additional logic in case the image has a strange
			// aspect ratio. For example, a panorama may have a much larger
			// width than height. In these cases the total pixels might still
			// end up being too large to fit comfortably in memory, so we should
			// be more aggressive with sample down the image (=larger
			// inSampleSize).

			final float totalPixels = width * height;

			// Anything more than 2x the requested pixels we'll sample down
			// further
			final float totalReqPixelsCap = reqWidth * reqHeight * 2;

			while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
				inSampleSize++;
			}
		}
		return inSampleSize;
	}
}
